#pragma once
#include"Socket.hpp"

#include"Log.hpp"
#include"InetAddr.hpp"

using namespace socket_ns;

static const uint16_t gport=8888;

using service_io_t =std::function<void(SockSPtr,InetAddr &)>;


class TcpServer
{
public:
    TcpServer(service_io_t service,uint16_t port=gport):
    _service(service),
    _listensock(std::make_shared<TcpSocket>()),
    _port(port),
    _isrunning(false)
    {
        _listensock->BulidListenSocket(_port);
    }
    
    class ThreadDate
    {
    public:
        SockSPtr _sockfd;
        TcpServer* _self;
        InetAddr _addr;
    public:
        ThreadDate(SockSPtr sock,TcpServer* self,InetAddr addr):_sockfd(sock),_self(self),_addr(addr){}
    };
    void Loop()
    {
        // signal(SIGCHLD,SIG_IGN);对子进程进行忽略不需要回收了，最好方案
        _isrunning=true;
        while(_isrunning)
        {
            InetAddr client;
            SockSPtr newsock= _listensock->Accepter(&client);
            if(newsock==nullptr)continue;
            LOG(INFO,"get a new link client info :%s socket:%d\n",client.Ip().c_str(),newsock->Sockfd());
            
            //多线程版本
            pthread_t tid;
            ThreadDate* td=new ThreadDate(newsock,this,client);
            pthread_create(&tid,nullptr,Execute,td);    
        }

        _isrunning=false;
    }
    static void* Execute(void* args)
    {
        pthread_detach(pthread_self());
        ThreadDate* td=static_cast<ThreadDate *>(args);
        td->_self->_service(td->_sockfd,td->_addr);
        td->_sockfd->Close();
        delete td;
        return nullptr;
    }
    
    ~TcpServer()
    {}
private:
    uint16_t _port;
    SockSPtr _listensock;
    bool _isrunning;
    service_io_t _service;
};
